package com.lanhao.aot.carrierintegration.imile;

import java.io.File;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.beust.jcommander.internal.Maps;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpStatus;

public class IMileUtil {
	private static final Logger LOG = LoggerFactory.getLogger(IMileUtil.class);
	
	private static final String ENV = "PROD";
	
	private static String BASE_URL = "https://openapi.52imile.cn";
	private static String SECRET_KEY = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAKXFH+uL7Phl6H0C";
	private static String CUSTOMER_ID = "C21018634";

	private static final String GRANT_URL = "/auth/accessToken/grant";
	private static final String CREATE_ORDER_URL = "/client/order/v2/createOrder";
	private static final String REPRINT_LABEL_URL = "/client/order/reprintOrder";
	private static final String ORDER_DELETE_URL = "/client/order/deleteOrder";

	private static final String FORMAT = "json";
	private static final String SIGN_METHOD = "MD5";
	private static final String TIME_ZONE = "+8";
	private static final String VERSION = "1.0.0";
	private static final String ORDER_TYPE = "200";
	private static final String DEFAULT_WEIGHT = "0.25";

	public static final String SA = "SA"; // 沙特阿拉伯
	public static final String AE = "AE"; // 阿联酋
	public static final String KW = "KW"; // 科威特
	public static final String OM = "OM"; // 阿曼
	public static final String BH = "BH"; // 巴林
	public static final String QA = "QA"; // 卡塔尔

	public static final Map<String, String> LOGISTICS_PRODUCT_CODE_MAP = Maps.newHashMap();

	static {
		if("TEST".equals(ENV)) {
			BASE_URL = "https://openapi.52imile.cn";
			SECRET_KEY = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAKXFH+uL7Phl6H0C";
			CUSTOMER_ID = "C21018634";
			
			LOGISTICS_PRODUCT_CODE_MAP.put(SA, "LP210081");
			LOGISTICS_PRODUCT_CODE_MAP.put(AE, "LP210080");
			LOGISTICS_PRODUCT_CODE_MAP.put(KW, "LP210084");
			LOGISTICS_PRODUCT_CODE_MAP.put(OM, "LP210082");
			LOGISTICS_PRODUCT_CODE_MAP.put(BH, "LP210085");
			LOGISTICS_PRODUCT_CODE_MAP.put(QA, "LP210083");
		} else {
			BASE_URL = "https://openapi.imile.com";
			SECRET_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIPn3vKSsSF+4HMm";
			CUSTOMER_ID = "C2103841501";
			
			LOGISTICS_PRODUCT_CODE_MAP.put(SA, "LP210010");
			LOGISTICS_PRODUCT_CODE_MAP.put(AE, "LP210014");
			LOGISTICS_PRODUCT_CODE_MAP.put(KW, "LP21005901");
			LOGISTICS_PRODUCT_CODE_MAP.put(OM, "LP21010301");
			LOGISTICS_PRODUCT_CODE_MAP.put(BH, "LP21007801");
			LOGISTICS_PRODUCT_CODE_MAP.put(QA, "LP21006701");
		}
	}

	public static void main(String[] args) {
//		getGrantToken();
//		String countryCode = "QA";
//		createOrder(countryCode);
		
		rePrintLabel("6012624522979", "", null);
	}

	public static Pair<Boolean, String> getGrantToken() {
		JSONObject body = new JSONObject();
		body.put("grantType", "clientCredential");
		JSONObject request = buildRequestParam(body, "");
		String url = BASE_URL + GRANT_URL;
		LOG.info("请求iMile获取token信息，url={}, 请求入参={}", url, request.toString());
		String respBody = HttpRequest.post(url).setConnectionTimeout(1000).setReadTimeout(10000)
				.body(request.toString()).execute().body();
		LOG.info("请求iMile获取token信息，返回结果respBody={}", respBody);
		if (StringUtils.isNotBlank(respBody)) {
			JSONObject respObject = JSON.parseObject(respBody);
			Integer code = respObject.getInteger("code");
			String message = respObject.getString("message");
			if (code == HttpStatus.HTTP_OK) {
				JSONObject dataObject = respObject.getJSONObject("data");
				String token = dataObject.getString("accessToken");
				Integer expiresIn = dataObject.getInteger("expiresIn");
				LOG.info("获取token成功，token={}, expiresIn={}", token, expiresIn);
				return Pair.of(true, token);
			}
			return Pair.of(false, message);
		}
		return Pair.of(false, "调用获取token接口返回为空");
	}

	public static Pair<Boolean, String> createOrder(String countryCode) {
		Pair<Boolean, String> tr = getGrantToken();
		if (!tr.getLeft()) {
			return tr;
		}
		String orderNo = UUID.fastUUID().toString(true);
		JSONObject body = new JSONObject();
		body.put("orderNo", orderNo);
		body.put("orderType", ORDER_TYPE);
		body.put("originalWaybillNo", "");

		Pair<JSONObject, JSONObject> info = buildCountrySenderAndConsigeeInfo(countryCode);

		// 收件人信息
		JSONObject senderInfo = info.getLeft();
		JSONObject consigneeInfo = info.getRight();

		body.put("senderInfo", senderInfo);
		body.put("consigneeInfo", consigneeInfo);

		JSONObject serviceInfo = new JSONObject();
		serviceInfo.put("logisticsProductCode", LOGISTICS_PRODUCT_CODE_MAP.get(countryCode));
//		serviceInfo.put("pickupService", "0"); // 是否需要提货增值服务（ 0-否, 1-是，默认0）
		serviceInfo.put("expectedPickupDate", "");
		// Delivery：送货上门 Self：客户自提 Self-dropoff：顾客自送（仅限退货退款订单）
		serviceInfo.put("deliveryService", "Delivery");
		serviceInfo.put("deliveryRequirements", "");
		body.put("serviceInfo", serviceInfo);

		JSONObject packageInfo = new JSONObject();
		packageInfo.put("goodsType", "Normal");
		packageInfo.put("paymentMethod", "PPD");
		packageInfo.put("collectingMoney", "0");
		packageInfo.put("clientDeclaredValue", "0.01");
		packageInfo.put("clientDeclaredCurrency", "Local");
		packageInfo.put("productValue", "0.01");
		packageInfo.put("productValueCurrency", "Local");
//		packageInfo.put("length", "10");
//		packageInfo.put("width", "20");
//		packageInfo.put("high", "30");
		packageInfo.put("totalVolume", "100");
		packageInfo.put("grossWeight", DEFAULT_WEIGHT);
		body.put("packageInfo", packageInfo);

		JSONArray skuInfos = new JSONArray();
		JSONObject skuInfo = new JSONObject();
		skuInfo.put("skuNo", "");
		skuInfo.put("skuName", "AnHe Goods");
		skuInfo.put("skuQty", "1");
		skuInfo.put("skuDesc", "");
		skuInfo.put("skuDeclaredValue", "");
		skuInfo.put("skuWeight", 0.01);
		skuInfo.put("skuVolume", "");
		skuInfo.put("skuHsCode", "");
		skuInfo.put("skuUrl", "");
		skuInfos.add(skuInfo);
		body.put("skuInfos", skuInfos);

		String accessToken = tr.getRight();
		
		JSONObject request = buildRequestParam(body, accessToken);

		String url = BASE_URL + CREATE_ORDER_URL;
		LOG.info("请求iMile创建订单信息，url={}, 请求入参={}", url, request.toString());
		String respBody = HttpRequest.post(url).setConnectionTimeout(1000).setReadTimeout(10000)
				.body(request.toString()).execute().body();
		LOG.info("请求iMile创建订单信息，返回结果respBody={}", respBody);

		if (StringUtils.isNotBlank(respBody)) {
			JSONObject respObject = JSON.parseObject(respBody);
			Integer code = respObject.getInteger("code");
			String message = respObject.getString("message");
			if (code == HttpStatus.HTTP_OK) {
				JSONObject dataObject = respObject.getJSONObject("data");
				String expressNo = dataObject.getString("expressNo");
				String imileAwb = dataObject.getString("imileAwb");
				LOG.info("iMile创建订单成功expressNo={}", expressNo);
				if (StringUtils.isBlank(imileAwb)) {
					Pair<Boolean, String> rePrintLabel = rePrintLabel(expressNo, countryCode, accessToken);
					if (rePrintLabel.getLeft()) {
						imileAwb = rePrintLabel.getRight();
					} else {
						LOG.info("查询面单base64信息失败，原因：" + rePrintLabel.getRight());
					}
				}
				Base64.decodeToFile(imileAwb, new File("D:/" + countryCode + "_" + expressNo + ".PDF"));
				return Pair.of(true, "下单成功");
			}
			return Pair.of(false, message);
		}

		return Pair.of(false, "调用获取token接口返回为空");
	}
	
	public static Pair<Boolean, String> rePrintLabel(String expressNo, String countryCode, String accessToken) {
		if (StringUtils.isBlank(accessToken)) {
			Pair<Boolean, String> tr = getGrantToken();
			if (!tr.getLeft()) {
				return tr;
			}
			accessToken = tr.getRight();
		}
		JSONObject body = new JSONObject();
		body.put("orderCode", expressNo);
		body.put("orderCodeType", "2");
		JSONObject request = buildRequestParam(body, accessToken);
		String url = BASE_URL + REPRINT_LABEL_URL;
		LOG.info("查询iMile面单Base64信息，url={}, 请求入参={}", url, request.toString());
		String respBody = HttpRequest.post(url).setConnectionTimeout(1000).setReadTimeout(10000)
				.body(request.toString()).execute().body();
		LOG.info("查询iMile面单Base64信息，返回结果respBody={}", respBody);
		if (StringUtils.isNotBlank(respBody)) {
			JSONObject respObject = JSON.parseObject(respBody);
			Integer code = respObject.getInteger("code");
			String message = respObject.getString("message");
			if (code == HttpStatus.HTTP_OK) {
				JSONObject dataObject = respObject.getJSONObject("data");
				String imileAwb = dataObject.getString("imileAwb");
//				Base64.decodeToFile(imileAwb, new File("D:/" + countryCode + "_" + expressNo + ".PDF"));
				return Pair.of(true, imileAwb);
			}
			return Pair.of(false, message);
		}
		return Pair.of(false, "调用查询面单Base64信息接口返回为空");
	}

	/**
	 * 构建请求参数 签名拼接规则：
	 * {secretKey}accessToken{accessToken}customerId{customerId}format{format}signMethod{signMethod}timeZone{timeZone}timestamp{timestamp}version{version}{body}{secretKey}
	 * 
	 * @param body
	 * @param accessToken
	 * @return
	 */
	public static JSONObject buildRequestParam(JSONObject body, String accessToken) {
		String timestamp = String.valueOf(System.currentTimeMillis());
		StringBuilder sb = new StringBuilder();
		sb.append(SECRET_KEY);
		if (StringUtils.isNotBlank(accessToken)) {
			sb.append("accessToken" + accessToken);
		}
		sb.append("customerId" + CUSTOMER_ID);
		sb.append("format" + FORMAT);
		sb.append("signMethod" + SIGN_METHOD);
		sb.append("timeZone" + TIME_ZONE);
		sb.append("timestamp" + timestamp);
		sb.append("version" + VERSION);
		sb.append(body.toJSONString());
		sb.append(SECRET_KEY);
		String sign = DigestUtils.md5Hex(sb.toString());

		JSONObject request = new JSONObject();
		if (StringUtils.isNotBlank(accessToken)) {
			request.put("accessToken", accessToken);
		}
		request.put("customerId", CUSTOMER_ID);
		request.put("sign", sign);
		request.put("signMethod", SIGN_METHOD);
		request.put("format", FORMAT);
		request.put("version", VERSION);
		request.put("timestamp", timestamp);
		request.put("timeZone", TIME_ZONE);
		request.put("param", body);

		return request;
	}

	private static Pair<JSONObject, JSONObject> buildCountrySenderAndConsigeeInfo(String countryCode) {
		// 收件人信息 仓库信息
		JSONObject senderInfo = new JSONObject();
		// 发件人信息
		JSONObject consigneeInfo = new JSONObject();
		if (SA.equals(countryCode)) {
			senderInfo.put("contacts", "SA-RTN-AE");
			senderInfo.put("phone", "505012345");
			senderInfo.put("province", "RIYARDH");
			senderInfo.put("city", "RIYARDH");
			senderInfo.put("address", "BUILDING NO.3266，AL MADINNH ROAD	");
			senderInfo.put("zipCode", "12345");

			consigneeInfo.put("contacts", "عارفالصادقامام");
			consigneeInfo.put("phone", "551334949");
			consigneeInfo.put("province", "Qassim");
			consigneeInfo.put("city", "Buraidah");
			consigneeInfo.put("address", "AttarafeyaRoad(طريقالطرفية)");
			consigneeInfo.put("zipCode", "52367");

		} else if (AE.equals(countryCode)) {
			senderInfo.put("contacts", "Farooq");
			senderInfo.put("phone", "00971507250857	");
			senderInfo.put("province", "UMM AL QUWAIN");
			senderInfo.put("city", "UMM AL QUWAIN");
			senderInfo.put("address", "WAREHOUSE NO.26D,INJAZ ZONE COMPLEX,NEW INDUSTRIALS AREA	");
			senderInfo.put("zipCode", "42345");

			consigneeInfo.put("contacts", "AbdelwahidAhmed");
			consigneeInfo.put("phone", "506440667");
			consigneeInfo.put("province", "Sharjah");
			consigneeInfo.put("city", "Sharjah");
			consigneeInfo.put("address", "Sharjahvilla1441");
			consigneeInfo.put("zipCode", "6585");
		} else if (KW.equals(countryCode)) {
			senderInfo.put("contacts", "KW-RTN");
			senderInfo.put("phone", "505012345");
			senderInfo.put("province", "");
			senderInfo.put("city", "AL NASEEM");
			senderInfo.put("address", "KW WareHouse ADDRESS");
			senderInfo.put("zipCode", "35513");

			consigneeInfo.put("contacts", "KunKun-KW");
			consigneeInfo.put("phone", "509012345");
			consigneeInfo.put("province", "");
			consigneeInfo.put("city", "AL NASEEM");
			consigneeInfo.put("address", "KW Shipper ADDRESS");
			consigneeInfo.put("zipCode", "35513");
		} else if (OM.equals(countryCode)) {
			senderInfo.put("contacts", "OM-RTN");
			senderInfo.put("phone", "505012345");
			senderInfo.put("province", "");
			senderInfo.put("city", "Berwick");
			senderInfo.put("address", "OM WareHouse ADDRESS");
			senderInfo.put("zipCode", "999046");

			consigneeInfo.put("contacts", "KunKun-OM");
			consigneeInfo.put("phone", "509012345");
			consigneeInfo.put("province", "");
			consigneeInfo.put("city", "Berwick");
			consigneeInfo.put("address", "OM Shipper ADDRESS");
			consigneeInfo.put("zipCode", "999046");
		} else if (BH.equals(countryCode)) {
			senderInfo.put("contacts", "BH-RTN");
			senderInfo.put("phone", "505012345");
			senderInfo.put("province", "");
			senderInfo.put("city", "Manama");
			senderInfo.put("address", "BH WareHouse ADDRESS");
			senderInfo.put("zipCode", "323");

			consigneeInfo.put("contacts", "KunKun-BH");
			consigneeInfo.put("phone", "509012345");
			consigneeInfo.put("province", "");
			consigneeInfo.put("city", "Manama");
			consigneeInfo.put("address", "BH Shipper ADDRESS");
			consigneeInfo.put("zipCode", "323");
		} else if (QA.equals(countryCode)) {
			senderInfo.put("contacts", "QA-RTN");
			senderInfo.put("phone", "505012345");
			senderInfo.put("province", "");
			senderInfo.put("city", "Doha");
			senderInfo.put("address", "QA WareHouse ADDRESS");
			senderInfo.put("zipCode", "+974");

			consigneeInfo.put("contacts", "KunKun-QA");
			consigneeInfo.put("phone", "509012345");
			consigneeInfo.put("province", "");
			consigneeInfo.put("city", "Doha");
			consigneeInfo.put("address", "QA Shipper ADDRESS");
			consigneeInfo.put("zipCode", "+974");
		}
		// 仓库信息
		senderInfo.put("addressType", "warehouse"); // 本次对接服务可以去掉
		senderInfo.put("country", countryCode);
		senderInfo.put("contactCompany", "");
		senderInfo.put("backupPhone", "");
		senderInfo.put("area", "");
		senderInfo.put("longitude", "");
		senderInfo.put("latitude", "");
		senderInfo.put("email", "");
		senderInfo.put("suburb", "");
		senderInfo.put("street", "");
		senderInfo.put("externalNo", "");
		senderInfo.put("internalNo", "");

		// 发件人信息
		consigneeInfo.put("addressType", "customer");
		consigneeInfo.put("country", countryCode);
		consigneeInfo.put("contactCompany", "");
		consigneeInfo.put("backupPhone", "");
		consigneeInfo.put("email", "");
		consigneeInfo.put("area", "");
		consigneeInfo.put("longitude", "");
		consigneeInfo.put("latitude", "");
		consigneeInfo.put("suburb", "");
		consigneeInfo.put("street", "");
		consigneeInfo.put("externalNo", "");
		consigneeInfo.put("internalNo", "");
		consigneeInfo.put("idNo", "");
		consigneeInfo.put("idCardFrontImg", "");
		consigneeInfo.put("idCardBackImg", "");

		return Pair.of(senderInfo, consigneeInfo);
	}
	
	public static Pair<Boolean, String> deleteOrder(String orderCode, String expressNo, String countryCode,
			String accessToken) {
		if (StringUtils.isBlank(accessToken)) {
			Pair<Boolean, String> tr = getGrantToken();
			if (!tr.getLeft()) {
				return tr;
			}
			accessToken = tr.getRight();
		}
		JSONObject body = new JSONObject();
		body.put("orderCode", orderCode); // 客户订单号
		body.put("waybillNo", expressNo); // iMile运单号
		JSONObject request = buildRequestParam(body, accessToken);
		String url = BASE_URL + ORDER_DELETE_URL;
		LOG.info("删除iMile订单信息，url={}, 请求入参={}", url, request.toString());
		String respBody = HttpRequest.post(url).setConnectionTimeout(1000).setReadTimeout(10000)
				.body(request.toString()).execute().body();
		LOG.info("删除iMile订单信息，返回结果respBody={}", respBody);
		if (StringUtils.isNotBlank(respBody)) {
			JSONObject respObject = JSON.parseObject(respBody);
			Integer code = respObject.getInteger("code");
			String message = respObject.getString("message");
			if (code == HttpStatus.HTTP_OK) {
				return Pair.of(true, "删除成功");
			}
			return Pair.of(false, message);
		}
		return Pair.of(false, "调用删除iMile订单信息接口返回为空");
	}
	
	
}
